home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir36 / ask_dos.zip / ASK.ASM < prev    next >
Assembly Source File  |  1994-03-05  |  10KB  |  321 lines

  1. TITLE Program ASK.ASM - GROUP directive used in construct for .COM file.
  2.  
  3. ; *************************************************************************
  4. ; *      Date: March 31, 1992     Use: Interactive Batch Processing.      *
  5. ; *                                                                       *
  6. ; *             Written by: Patrick Whittle  (519) 945-7596               *
  7. ; *                 Revised to .COM format March 5, 1994                  *
  8. ; *************************************************************************
  9.  
  10. CR       EQU 0Dh
  11. LF       EQU 0Ah
  12. SPACE    EQU 20h
  13.  
  14. comGrp   GROUP dSeg1, dSeg2, cSeg
  15.  
  16. cSeg     SEGMENT WORD 'CODE'            ; Give names to our segments.
  17. cSeg     ENDS
  18. dSeg1    SEGMENT WORD PUBLIC 'DATA'
  19. dSeg1    ENDS
  20. dSeg2    SEGMENT WORD PUBLIC 'DATA'
  21. dSeg2    ENDS
  22.  
  23. dSeg1    SEGMENT        ; Data segment 1 for initialized data.
  24. ;
  25. MESSAGE  DB 'Batch Enhancer, written by Patrick Whittle, (519) 945-7596.', CR, LF, CR, LF
  26.          DB 'USAGE:', CR, LF
  27.          DB 09h, 'ASK [Prompt to display]', CR, LF
  28.          DB 09h, 'ASK [/?]', CR, LF, CR, LF
  29.          DB 'Returns DOS errorlevel.', CR, LF, 00h
  30. ;
  31. PROMPT   DB '(Y or N)? ', 00h
  32. YES      DB 'YES', 00h
  33. NO       DB 'NO', 00h
  34. ;
  35. ctrlText DB CR, LF, '<Break>', CR, LF, 00h
  36. dSeg1    ENDS
  37.  
  38. dSeg2    SEGMENT        ; Data segment 2 for un-initialized data.
  39. ;
  40. errorlevel       DB ?
  41. origSegment      DW ?
  42. origOffset       DW ?
  43. ;
  44. dSeg2    ENDS
  45.  
  46. cSeg     SEGMENT
  47.  
  48.       ASSUME   cs:comGrp, ds:comGrp, es:comGrp, ss:comGrp
  49.  
  50.       ORG 100h                 ; Start of CS and DS
  51.  
  52. Main:
  53.     call   grabCommandline            ; Command-line tail given?
  54.     jcxz   sendInstruction            ; If not, send out prompt.
  55.  
  56.     cmp    WORD PTR [si], '?/'
  57.     je     sendHelp
  58.     mov    bx, si              ; SI contains pointer to cmd-line argument.
  59.     call   dispString          ; Display user supplied string.
  60.  
  61. ContinueMain:
  62.     call   getIntVector
  63.     lea    dx, ctrlBreakHandler
  64.     call   setIntVector
  65.     call   Validate            ; Compare inputed keys with Y and N.
  66.  
  67. Stop:
  68.     push   ds
  69.     mov    dx, comGrp:origOffset
  70.     mov    ds, comGrp:origSegment
  71.     call   setIntVector
  72.     pop    ds
  73.  
  74. DOSexit:
  75.     mov    ah, 4Ch                ; Program Terminate with errorlevel.
  76.     mov    al, comGrp:errorlevel
  77.     int    21h
  78.  
  79. sendInstruction:
  80.     call   OutPut
  81.     jmp    ContinueMain        ; Proceed and validate input.
  82.  
  83. sendHelp:
  84.     lea    bx, MESSAGE
  85.     call   dispString
  86.     mov    comGrp:errorlevel, 00h
  87.     jmp    DOSexit
  88.  
  89. ;---------------------------
  90.  
  91. Validate PROC NEAR
  92.     call   AcceptChar
  93.     cmp    al, 'Y'             ; Is this the "Y" character?
  94.     je     YWasTyped
  95.     cmp    al, 'N'             ; Is this the "N" character?
  96.     je     NWastyped
  97.     call   Cr_Lf
  98.     call   OutPut              ; Conditions not met.
  99.     jmp    Validate            ; Unconditional jump.
  100.  
  101. YWasTyped:
  102.     lea    bx, comGrp:YES      ; Load Effective Address into BX.
  103.     call   dispString
  104.     call   Cr_Lf
  105.     mov    comGrp:errorlevel, 00h     ; Set DOS errorlevel to zero.
  106.     jmp    CharactersFine
  107.  
  108. NWasTyped:
  109.     lea    bx, comGrp:NO
  110.     call   dispString
  111.     call   Cr_Lf
  112.     mov    comGrp:errorlevel, 01h     ; Set DOS errorlevel to one.
  113.  
  114. CharactersFine:
  115.     ret
  116.  
  117. Validate ENDP
  118.  
  119. Output PROC NEAR
  120.     lea    bx, PROMPT
  121.     call   dispString
  122.     ret                        ; Return to calling module.
  123.  
  124. Output ENDP
  125.  
  126. dispString PROC NEAR
  127.     mov    ah, 02h
  128.  
  129. sendPrompt:
  130.     cmp    BYTE PTR [bx], 00h
  131.     je     promptDone
  132.     mov    dl, BYTE PTR [bx]
  133.     int    21h
  134.     inc    bx
  135.     jmp    sendPrompt
  136.  
  137. promptDone:
  138.     ret
  139.  
  140. dispString ENDP
  141.  
  142. AcceptChar PROC NEAR
  143.     mov    ah, 08              ; Accept character function.
  144.     int    21h
  145.     call   upCase
  146.     ret                        ; Return to calling module.
  147.  
  148. AcceptChar ENDP
  149.  
  150. Cr_Lf PROC NEAR
  151.     mov    ah, 02h
  152.     mov    dl, CR
  153.     int    21h
  154.     mov    dl, LF
  155.     int    21h
  156.     ret                        ; Return to calling module.
  157.  
  158. Cr_Lf ENDP
  159.  
  160. grabCommandline PROC NEAR
  161. ;
  162. ; Any command-line parameters supplied by the user will be passed by DOS into
  163. ; the executing programs PSP (Program Segment Prefix) area.  The default PSP
  164. ; area in a program, weather in .EXE format or .COM format, is between offset
  165. ; 0000 and 0100h of the programs data segment. Since a program in .COM format
  166. ; has its code, data, and stack stored in the same segment of memory
  167. ; (i.e. CS=DS=SS respectively) it is necessary that the code of .COM programs
  168. ; always starts at offset 0100h (see ORG directive at start of this program).
  169. ;
  170. ; This PROCedure uses SI register to access the PSP making use of a flag set
  171. ; by DOS at offset 80h.  This single byte indicates weather a command-line
  172. ; argument was supplied or not.  If the value at offset 80h is zero, then
  173. ; no command-line argument was supplied.  If the value is non-zero, the
  174. ; contents of offset 80h will hold a byte count for the supplied argument.
  175. ;
  176. ; In this procedure, the CX register will receive a copy of the byte at
  177. ; offset 80h to be used in calculating the end address of the string.  All
  178. ; preceding, and trailing spaces will be discarded.
  179. ;
  180. ; Inputs:
  181. ;        None
  182. ;
  183. ; Output:
  184. ;        si - Pointer to start of user supplied string.
  185. ;        cx - zero if no command-line argument given.
  186. ;
  187. ; Registers modified:
  188. ;        cx, si
  189. ;    
  190.     xor    cx, cx               ; Zero out cx register.
  191.     mov    si, 80h
  192.     cmp    BYTE PTR [si], 00h
  193.     je     grabDone             ; If byte at offset 80h is 0 then there were
  194.                                 ;    no arguments.
  195.     mov    cl, BYTE PTR [si]    ; Move byte pointed to by SI into CL register.
  196.  
  197. findNonblank:
  198.     inc    si
  199.     cmp    BYTE PTR [si], SPACE
  200.     jne    startFound
  201.     loop   findNonblank         ; Assume length of argument is one less now
  202.                                 ; as loop decrements CX register.
  203. startFound:
  204.     jcxz   grabDone             ; If CX is zero then the user has supplied
  205.                                 ;    a string of spaces and just pressed ┘
  206.     push   si                   ; Save start of argument.
  207.     add    si, cx               ; To point to end.
  208.  
  209. testForTrailingBlank:
  210.     dec    si
  211.     cmp    BYTE PTR [si], SPACE
  212.     jne    terminateArgument
  213.     loop   testForTrailingBlank      ; Remove unwanted spaces.
  214.  
  215. terminateArgument:
  216.     mov    WORD PTR [si+1], 0020h    ; Add space and ensure string is ASCIIZ.
  217.     pop    si
  218.  
  219. grabDone:
  220.     ret
  221.  
  222. grabCommandline ENDP
  223.  
  224. ctrlBreakHandler PROC NEAR
  225. ;
  226. ; This PROCedure is the replacement interrupt handler for int 23h - the 
  227. ; Ctrl-Break interrupt.  Regardless where the machine is currently executing
  228. ; in memory, the Ctrl-C interrupt will instantly force execution to branch
  229. ; to this area. The int 23h handler will be restored when ASK.COM terminates.
  230. ;
  231. ; The value of all segment registers will be unchanged when an interrupt is
  232. ; encountered.  Since this program is not a TSR (Terminate and Stay Resident)
  233. ; we don't need to worry about initializing DS to point to our data for
  234. ; example, or any other segment registers.
  235. ;
  236. ; If this were a TSR program or device driver on the other hand, segment
  237. ; registers would not contain values reflecting the location of code, data,
  238. ; etc., for ASK.COM, they would contain values that were part of some other
  239. ; executing program at the time of the interrupt.
  240. ;
  241. ; The way the internal interrupt vectors are designed on Intel machines is
  242. ; such that only the CS:IP registers (code segment:instruction pointer) are
  243. ; modified when a certain interrupt is encountered, and a FAR return address 
  244. ; is then pushed onto the stack (segment:offset = current execution address
  245. ; of interrupted program).  It is up to the "interruptor" (i.e. the device
  246. ; driver, or TSR program) to first set up segment registers to point to its 
  247. ; needed data, stack etc., and when finished, restore CS:IP with an iret
  248. ; instruction once the service requested of the device driver is complete.
  249. ;
  250. ; Output:
  251. ;        Program terminates with DOS errorlevel 2
  252. ;
  253. ; Registers modified:
  254. ;        ax, bx, cx
  255. ;    
  256.     mov    ax, cs                 ; The next three move intstructions are
  257.     mov    ds, ax                 ; not needed in the context of this program,
  258.     mov    es, ax                 ; but are included for demonstration.
  259.     mov    comGrp:errorlevel, 02h
  260.     lea    bx, comGrp:ctrlText
  261.     call   dispString
  262.  
  263.     mov    ax, 0C00h              ; Flush keyboard buffer.
  264.     int    21h
  265.     jmp    Stop
  266.  
  267. ctrlBreakHandler ENDP
  268.  
  269. upCase PROC NEAR
  270. ;
  271. ; This function returns the corresponding upper-case letter for
  272. ; the lower-case letter passed in al.
  273. ;
  274. ; Input:
  275. ;        al   - contains the ASCII value for a lower-case letter
  276. ; Output:
  277. ;        al   - contains the ASCII value for the corresponding upper-case
  278. ;               letter.
  279. ;
  280. ; Registers modified:
  281. ;        al
  282. ;
  283. ; Convert the letter in AL to upper-case.
  284. ;
  285.     cmp    al, 'a'
  286.     jb     upcas1
  287.     cmp    al, 'z'
  288.     ja     upcas1
  289.     sub    al, 20h
  290.  
  291. upcas1:
  292.     ret
  293.  
  294. upCase ENDP
  295.  
  296. setIntVector PROC NEAR
  297. ;
  298. ; DX register must be initialized first before calling.
  299. ;
  300.     mov    ax, 2523h
  301.     int    21h
  302.     ret
  303.  
  304. setIntVector ENDP
  305.  
  306. getIntVector PROC NEAR
  307.     push   es
  308.     mov    ax, 3523h             ; 23 is ctrl-break location in interrupt
  309.     int    21h                   ; vector table.
  310.  
  311.     mov    WORD PTR comGrp:origSegment, es
  312.     mov    WORD PTR comGrp:origOffset, bx
  313.     pop    es
  314.     ret
  315.  
  316. getIntVector ENDP
  317.  
  318. cSeg     ENDS
  319.  
  320. END      Main
  321.